<?xml version="1.0"
      encoding="utf-8"
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>LedControl</title>
<meta name="generator" content="http://txt2tags.sf.net" />
<link rel="stylesheet" type="text/css" href="lc.css" />
</head>
<body>

<div class="header" id="header">
<h1>LedControl</h1>
<h2>for the </h2>
<h3>Arduino</h3>
</div>

<div class="body" id="body">
<hr class="light" />
<a id="toc1" name="toc1"></a>
<h2>A arduino library for the MAX7221 and MAX7219</h2>
<p>
These two chips provide an easy way to control either an array of 64 LEDs 
or up to eight digits made of 7-segment displays with a minimum of electronic
components. Besides the chip itself you will need only a single resistor and one 
or two capacitors. Data is send to the chip using a SPI-compatible protocol using 3 of the digital pins 
on the arduino. If you want control more than eighth 7-segment displays (or more than 64 LEDs)
the chips can be cascaded. This library supports up to 8 cascaded devices, which add up to 512 LEDs
that can be lit individually. The good news is that you still need only 3 pins on your arduino board.
</p>
<p>
Here is a picture of my rather crappy (but working) testbed...
 <center><img align="middle" src="Max7221Setup.jpg" border="0" alt=""/></center> 
If you wonder whether the MAX7221 or the MAX7219 is more suitable for your project ... just go for the cheaper
one. But, if there is a chance you'll switch from the arduino to a different controller hardware, 
use the (more expensive) MAX7221. This one implements a fully SPI compatible interface. 
The LedControl library can cope with both types of devices, and the visual appearance 
to the user is the same.
</p>
<p>
Everything else you need to know about the MAX7221 and MAX7219 is to be found in the components data-sheet.
I will refer to the data-sheet in various places when describing the library functions. 
So you expect you to having read it before going on...
</p>
<hr class="light" />
<p>
<strong>Table of Contents</strong>
</p>
<div class="toc" id="toc">
    <ul>
    <li><a href="#toc1">A arduino library for the MAX7221 and MAX7219</a>
    </li>
    <li><a href="#library">The LedControl library</a>
    </li>
    <li><a href="#constructor">Creating a LedControl</a>
      <ul>
      <li><a href="#PowerSaving">Power saving mode</a>
      </li>
      <li><a href="#Initialization">Device initialization</a>
      </li>
      <li><a href="#ScanLimit">Limiting the number of digits</a>
      </li>
      <li><a href="#BrightnessControl">Setting display brightness</a>
      </li>
      <li><a href="#DisplayClear">Clearing the display</a>
      </li>
      </ul>
    </li>
    <li><a href="#MatrixControl">Controlling a Led matrix</a>
      <ul>
      <li><a href="#SingleMatrix">Lighting up a single Led</a>
      </li>
      <li><a href="#RowColMatrix">Lighting up a row or column on the matrix</a>
      </li>
      </ul>
    </li>
    <li><a href="#Seg7">Controlling 7-segment displays</a>
      <ul>
      <li><a href="#digits">Display decimal (or hex) numbers</a>
      </li>
      <li><a href="#Characters">Displaying characters</a>
      </li>
      </ul>
    </li>
    <li><a href="#Download">Download</a>
    </li>
    <li><a href="#Bugs">Known bugs</a>
    </li>
    <li><a href="#History">Revision History</a>
    </li>
    <li><a href="#Feedback">Feedback</a>
    </li>
    <li><a href="#SoftwareLicence">License (The software)</a>
    </li>
    <li><a href="#DocLicence">License (This document)</a>
    </li>
    </ul>

</div>
<hr class="light" />
<a id="library" name="library"></a>
<h2>The LedControl library</h2>
<p>
This is not the first time someone puts out code for the arduino and the MAX7221, but 
the focus has usually been on controlling LEDs layed out in some kind of rectangular matrix. 
I mainly use the chips to drive 7-segment displays, so I obviously want a function 
to display numbers (decimal and hexa-decimal) and also the limited set of alphanumeric characters 
that make (visual) sense for these types of displays.
</p>
<p>
I also wanted the code to be useful for a bigger audience, so there had to be a set of functions
to switch individual or groups of LEDs on and off. But there is no support for the 
<a href="http://wiring.org.co/reference/libraries/Sprite/index.html">Sprite</a>-library in LedControl.
Sprites are omitted mainly for saving precious memory on the arduino. 
Adding the LedControl-library to your code will cost you 1710 bytes on an ATMega168.
But this number is for the basic (do-nothing) application, where we only include the 
library-code without calling any of the functions. 
</p>
<pre>
//This app does nothing but waste (library-)memory
#include "LedControl.h"
void setup() {}
void loop() {}
</pre>
<p>
In my environment (arduino0007 on Linux) memory consumption for the compiled application
is raised from 4070 bytes (with the <code>#include</code>-statement commented out)
to 5780 from the code above. This is a little bit less than using the combination 
of the <code>Matrix/Sprite</code>-library that adds 2266 bytes to my code. (I actually have been wondering
for some time now where that memory is burned in the <code>Sprite</code>-library. <code>Sprite.h</code> alone 
is responsible for 1.2 kB of the 2.2 kB gone ...?) 
</p>
<p>
If you have been using the <code>Matrix/Sprite</code>-lib you will not be amused to hear this one : 
<em>The <code>LedControl</code>-lib uses a different scheme of addressing the individual LEDs on the hardware</em>
Ok, I know that this is annoying, but it should not be difficult to port an existing application
with the hints given later on. The reason I use a different hardware-address scheme for the LEDs,
is that the layout used in the <code>Matrix/Sprite</code>-lib would require some extra bit-twisting code 
for each change on an LEDs state. Since you will have to rewrite all of your code anyway when switching
libraries, I decided to put that extra burden upon you, just to save some more bytes and performance, sorry.
</p>
<p>
Other differences between existing library-code and the <code>LedControl</code>-lib are discussed 
along with the API-documentation.  
</p>
<a id="constructor" name="constructor"></a>
<h2>Creating a LedControl</h2>
<p>
All the libraries API-functions are called through an variable of type <code>LedControl</code>.
Lets go right into some basic code :
</p>
<pre>
/* we have to including the library */
#include "LedControl.h"

/* 
 * Create a new LedControl. 
 * We use pins 12,11 and 10 for the SPI interface
 * With our hardware we have connected pin 12 to the DATA IN-pin (1) of the first MAX7221
 * pin 11 is connected to the CLK-pin(13) of the first MAX7221
 * pin 10 is connected to the LOAD-pin(12) of the first MAX7221	 	
 * We will only have a single MAX7221 attached to the arduino 
 */
LedControl lc1=LedControl(12,11,10,1); 
</pre>
<p></p>
<p>
The first step is is obvious we have to include the <code>LedControl</code>-library. Then we create
an instance of type <code>LedControl</code> to talk to the MAX7221 devices. An <code>LedControl</code>
initialized with 4 arguments. The first 3 arguments are the pin-numbers you have used
inn the connection between the arduino-board and your (first) MAX72XX. You are free to choose
any of the digital IO-pins on the arduino, but some of the pins are used also for serial 
communication with other devices or have a led attached to (happens to be on pin 13 of my board).
In the example I choose pins 12,11 and 10. But this simply depends on your hardware setup.
The library does <strong>not</strong> check for the pin-numbers to be valid in any way. Passing in something stupid 
will break your app.
</p>
<p>
You don't have to set the pins to be used for the devices as outputs or initialize in any way.
The library handles all this for you. Simply hand them over to constructor and then leave them alone. 
</p>
<p>
Besides the 3 pin-numbers you will have to provide the number of MAX72XX devices you will 
be using on these 3 pins. The <code>LedControl</code>-lib allows you to address up to 8 devices
from a single <code>LedControl</code>-variable. There is a little performance penalty implied with 
each device you add to the chain. If that is not important to you (try it out in your code) you could
simply go for the maximum (8) devices. The library always uses the same amount of memory, no matter
how many devices you set in the argument. Only values between 1..8 are allowed here, otherwise
the default of 8 devices is used. 
Here is the prototype for a new <code>LedControl</code>-instance:
</p>
<pre>
/* 
 * Create a new controller 
 * Params :
 * int dataPin    The pin on the Arduino where data gets shifted out
 * int clockPin   The pin for the clock
 * int csPin      The pin for selecting the device when data is to be sent
 * int numDevices The maximum number of devices that can be controled
*/
LedControl(int dataPin, int clkPin, int csPin, int numDevices);
</pre>
<p>
If you need to control more than 8 MAX72XX, you'll have to create  
another <code>LedControl</code>-variable and sacrifice 3 more Pins on your arduino-board. 
</p>
<pre>
/* we have to include the library */
#include "LedControl.h"

// Create a new LedControl for 8 devices... 
LedControl lc1=LedControl(12,11,10,8); 

// ... and another one, now we control 1024 LEDs from an arduino, not bad!
// The second one must use different pins!
LedControl lc2=LedControl(9,8,7,8); 
</pre>
<p>
Obviously two instances of <code>LedControl</code> cannot share the pins on the arduino-board. 
</p>
<p>
There are no functions to replace or swap any of the pins later on. You can't even read
back the pin-numbers used by the <code>LedControl</code>. 
All this depends very much on the hardware you build, so implementing functions  for
this would be a waste of memory. But a function by which you can 
request the maximum number of devices attached to an <code>LedControl</code> can be very handy
when you want to iterate over the full list of MAX72XX devices attached to an <code>LedControl</code>.
Here is a piece of code that switches all of the MAX72XX-devices from power saving mode
into normal operation. I'll think you'll get the idea even though we haven't talked
about the <code>shutdown()</code> function yet...
</p>
<pre>
#include "LedControl.h"

// Create a new LedControl for 5 devices... 
LedControl lc1=LedControl(12,11,10,5); 
 
void setup() {
  for(int index=0;index&lt;lc1.getDeviceCount();index++) {
      lc1.shutdown(index,false);
  }
}
</pre>
<p>
We iterate over the list of devices by an index that runs from 0 to <code>getDeviceCount()-1</code>.
(That would be 0 to 4 in this piece of code.) The index is the <em>address</em> of each device. This <em>address</em>
will be the first argument of <strong>every</strong> function that sets a feature or a new (Led-)value on a device. 
Keep in mind that <code>getDeviceCount()</code> returns the number of devices attached, but the address of an device 
starts at 0 for the first one, 1 for the second one,.. <code>getDeviceCount()-1</code> for the last one.
Here is the prototype of the function:
</p>
<pre>
/*
 * Gets the maximum number of devices attached to this LedControl.
 * Returns :
 * int   the number of devices attached to this LedControl
*/
int LedControl::getDeviceCount();
</pre>
<p></p>
<a id="PowerSaving" name="PowerSaving"></a>
<h3>Power saving mode</h3>
<p>
LEDs consume quite a lot of energy when lit. For battery operated devices you'll
definitely want to save power by switching the whole display off, when the user
does not need it. A special command sequence can puts the MAX72XX into shutdown mode. 
The device will switch off all the LEDs on the display, but the data is retained 
inside the chip. You can even continue to send new data to the device 
when shutdown mode active. The data is processed even though the display is switched off.
As your code pulls the device out of shutdown mode again you will see the updated Data on your
Display. Here is an example for an <em>invisible</em> countdown:
</p>
<pre>
//create a new device
LedControl lc=LedControl(...);

//Here is an invisible countdown
int i=9;
//print that to the display
lc.setDigit(0,(byte)i,false);
//well see the number '9'
delay(1000);
//now switch the display off ...
lc.shutdown(true);
//and count down invisibly 
while(i&gt;1) {
    lc.setDigit(0,(byte)i,false);
    i--;
    delay(1000);
}
//when we switch the display on again it will show '1'
//which was updated during shutdown
lc.shutdown(false);
lc.setDigit(0,(byte)i,false);

</pre>
<p>
Here is the prototype for method <code>LedControl.shutdown()</code> 
</p>
<pre>
/* 
 * Set the shutdown (power saving) mode for the device
 * Params :
 * int addr   The address of the display to control
 * boolean b  If true the device goes into power-down mode. If false
 *            device goes into normal operation
*/
void shutdown(int addr, bool b);
</pre>
<p>
Please note that the MAX72XX is <strong>always</strong> in shutdown mode when the arduino is powered up. 
</p>
<a id="Initialization" name="Initialization"></a>
<h3>Device initialization</h3>
<p>
In the data-sheet for the MAX72XX you'll find a chapter about the power up settings of the devices. 
The library uses (almost) the same settings:
</p>
<ul>
<li>the display is blanked
</li>
<li>the device does not decode the data send to it
</li>
<li>the intensity is set to the minimum
</li>
<li>the device starts up in shutdown (power saving) mode 
</li>
<li>the maximum number of digits on the device is activated
</li>
</ul>

<p>
Starting up in power saving mode is always a good idea for an battery operated application,
but you will have to activate every device before use. If you go back to the code-example in
section <a href="#PowerSaving">Power saving mode</a> you'll see how that is done from the
<code>setup()</code> function of your application. 
</p>
<p>
Please do note that (different from the default hardware-setup of a MAX72XX) the library 
activates the maximum number of digits (8) on the device (see <a href="#ScanLimit">ScanLimit()</a>)
</p>
<a id="ScanLimit" name="ScanLimit"></a>
<h3>Limiting the number of digits</h3>
<p>
When a new LedControl is created it will activate all 8 digits on the display of all the devices.
So each lit digit will be switched on for 1/8 of a second by the multiplexer
that drives the digits. If you have any reason to limit the number of scanned digits, 
this is what happens : The LEDs get switched on more frequently, and therefore will be 
on for longer periods of time.n Setting the scan limit to 4 would mean that a lit Led 
is now switched on for 1/4 of a second, so the MAX7221 has to provide the current on the 
segment-driver for a longer period of time. 
</p>
<p>
Make sure you read the relevant section of the data-sheet on this topic, because it 
is actually possible to <strong>kill your MAX72XX</strong> by choosing a bad combination of the resistor that
limits the current through the LEDs and the number of digits scanned.
The only reason to tweak the scanlimit at all, is that the display looks too dark. But this
is most likely caused by the fact that you haven't raised the <a href="#BrightnessControl">intensity</a> on start up. 
Here's the prototype for <code>setScanLimit()</code>: 
</p>
<pre>
/* 
 * Set the number of digits (or rows) to be displayed.
 * See data-sheet for side effects of the scanlimit on the brightness
 * of the display.
 * Params :
 * int addr  The address of the display to control
 * int limit The number of digits to be displayed
 * Only values between 0 (only 1 digit) and 7 (all digits) are valid.
 */
void setScanLimit(int addr, int limit);
</pre>
<p></p>
<a id="BrightnessControl" name="BrightnessControl"></a>
<h3>Setting display brightness</h3>
<p>
There are three factors that determine the brightness of the display. The first one 
is the resistor <code>Rset</code> which limits the maximum current through the LEDs. The data-sheet 
has a section on selecting value for <code>Rset</code>. If its too small there is a chance the
LEDs draw more current than the MAX72XX can handle.
</p>
<p>
The second factor to display brightness is the scan limit of the display. 
From the <a href="#ScanLimit">ScanLimit</a> section you already know that I recommend to 
leave that parameter at its safe default.
</p>
<p>
But display brightness can be software controlled too, and this is what you should use. 
The lower and upper boundaries are set by the hardware (i.e. <code>Rset</code> and <em>ScanLimit</em>) but the 
<code>setIntensity()</code> method allows you to control brightness in a wide range. There are just
a few things to keep in mind:
</p>
<ul>
<li>When the MAX72XX is powered up the brightness is set to its darkest value. So you want
to raise the intensity from your code to something brighter. (But : if you don't see anything ...
did you read the section on <a href="#PowerSaving">power saving</a>?)  
</li>
<li>Lowest intensity does not mean the display isn't lit at all, its simply : dark!
</li>
<li>The range of values is from 0(dark) to 15(brightest). Every other value will be ignored.
</li>
</ul>

<p>
Here is the prototype for this method: 
</p>
<pre>
/* 
 * Set the brightness of the display.
 * Params:
 * int addr      the address of the display to control
 * int intensity the brightness of the display. 
 *               Only values between 0(darkest) and 15(brightest) are valid.
*/
void setIntensity(int addr, int intensity);
</pre>
<a id="DisplayClear" name="DisplayClear"></a>
<h3>Clearing the display</h3>
<p>
What can be said on this topic once you read the name of 
the method : <code>LedControl.clearDisplay()</code>?
</p>
<pre>
/* 
 * Switch all LEDs on the display off. 
 * Params:
 * int addr The address of the display to control
 */
void clearDisplay(int addr);
</pre>
<p>
All LEDs off after this call, that's it...  
</p>
<a id="MatrixControl" name="MatrixControl"></a>
<h2>Controlling a Led matrix</h2>
<p>
Ok, I made this one up. But with 7 MAX72XX it could actually be done...
</p>
<p>
<img align="middle" src="arduinomatrixsmall.jpg" border="0" alt=""/>
</p>
<p>
The picture of my setup at the top of the article reveals that I have only single 5x7 Matrix Led array.
With this Matrix I'm not even able to use the full 8x8 Matrix that could be controlled with a MAX72XX. 
But this cheap display is OK for testing the basic concepts the <code>LedControl</code> library 
provides for a Led matrix. 
</p>
<p>
There are 3 different functions for switching a Led in a Matrix on and off. We start with a function
that lets you control each of the LEDs individually... 
</p>
<a id="SingleMatrix" name="SingleMatrix"></a>
<h3>Lighting up a single Led</h3>
<p>
Here is the prototype for the function
</p>
<pre>
/* 
 * Set the status for a specific Led.
 * Params :
 * int addr  the address of the display to control
 * int row   the row in which the led is located 
 *           Only values between 0 and 7 are valid.
 * int col   the column in which the led is located
 *           Only values between 0 and 7 are valid.
 * boolean state If true the led is switched on, if false it is switched off
 */
void setLed(int addr, int row, int col, boolean state);
</pre>
<p>
It should be clear what the function does and what the 
 <code>addr</code> and the <code>state</code> arguments stand for. But what
is meant by a <code>row</code> and a <code>column</code> on the matrix. As the idea of the LEDs
layed out in the shape of matrix is a purely theoretical one, here is a schematic
that should clarify how the matrix is to connected to the pins of an MAX72XX.
 <center><img align="middle" src="ledmatrix.jpg" border="0" alt=""/></center> 
At the top and left side of the picture you see the pins on the MAX72XX, to which the LEDs 
have to be connected. Each of the LEDs has its position in the matrix written on the right
side. The row and column arguments should now be quite obvious:
There are 8 rows (indexed from 0..7) and 8 columns (also indexed from 0..7) in the matrix.
If we want to light up for instance the Led which is located at the very right of the 3'rd row from the 
top, simply take the index from the picture (2.7) and use is as the row and column arguments.
</p>
<pre>
//switch the led in the third row (index 2) eighth column (index 7) on
lc.setLed(0,2,7,true);   
delay(500);
lc.setLed(0,2,7,false);   
</pre>
<a id="RowColMatrix" name="RowColMatrix"></a>
<h3>Lighting up a row or column on the matrix</h3>
<p>
If you have to set the status of several LEDs it would blow up your code to use
<code>setLed()</code> for each Led to switch on or off. But there are two more functions
that set the value of either a row or a column in the matrix. 
With <code>setLed()</code> a boolean value was enough to signal the desired status of the Led.
But now we want to update 8 LEDs with a single function call, so the status of the 
individual LEDs needs to be encoded somehow.
Here again is the schematic of our LedMatrix but now I have added the values to be
set for each lit Led on a row or column.
 <center><img align="middle" src="led_r_c_matrix.jpg" border="0" alt=""/></center> 
Lets go through an example for setting a row in the matrix. We want to set the LEDs
in the 3'rd row from the top. The index for this row is 2. Now we only the LEDs
2.0, 2.3 and 2.6 to be lit in this row. All other LEDs shall be off.
We have to calculate the value for the call by adding up the <em>Row-Values</em> from
the schematic for each Led that is to be lit. A Led that is to remain dark does
not count here. Here is a table 
</p>
<table border="1">
<tr>
<th></th>
<th>Led 2.0</th>
<th>Led 2.1</th>
<th>Led 2.2</th>
<th>Led 2.3</th>
<th>Led 2.4</th>
<th>Led 2.5</th>
<th>Led 2.6</th>
<th>Led 2.7</th>
</tr>
<tr>
<td align="right">On</td>
<td align="center">Yes</td>
<td align="center">No</td>
<td align="center">No</td>
<td align="center">Yes</td>
<td align="center">No</td>
<td align="center">No</td>
<td align="center">Yes</td>
<td align="center">No</td>
</tr>
<tr>
<td align="right">Row-Value</td>
<td align="center">128</td>
<td align="center">0</td>
<td align="center">0</td>
<td align="center">16</td>
<td align="center">0</td>
<td align="center">0</td>
<td align="center">2</td>
<td align="center">0</td>
<td align="right">=146 (128+16+2)</td>
</tr>
</table>

<p>
In your code you would use <code>lc.setRow(0,2,146)</code> to set this row on the first MAX72XX
attached to the arduino.
</p>
<p>
The <code>setRow()</code>-call works also much faster than calling <code>setLed()</code> in turn for each
Led. So use this one wherever you can.
</p>
<p>
What can be done for <em>rows</em> can also be achieved with <em>columns</em>. The <code>setColumn()</code> method 
does the same thing for the vertical columns in the schematic. 
In the sixth column (remember index = 5) we want the 4 LEDs at the bottom to be lit. A table 
for the value to be passed into <code>setColumn()</code> would look like this 
</p>
<table border="1">
<tr>
<th></th>
<th>Led 0.5</th>
<th>Led 1.5</th>
<th>Led 2.5</th>
<th>Led 3.5</th>
<th>Led 4.5</th>
<th>Led 5.5</th>
<th>Led 6.5</th>
<th>Led 7.5</th>
</tr>
<tr>
<td align="right">On</td>
<td align="center">No</td>
<td align="center">No</td>
<td align="center">No</td>
<td align="center">No</td>
<td align="center">Yes</td>
<td align="center">Yes</td>
<td align="center">Yes</td>
<td align="center">Yes</td>
</tr>
<tr>
<td align="right">Column-Value</td>
<td align="center">0</td>
<td align="center">0</td>
<td align="center">0</td>
<td align="center">0</td>
<td align="center">8</td>
<td align="center">4</td>
<td align="center">2</td>
<td align="center">1</td>
<td align="right">=16 (8+4+2+1)</td>
</tr>
</table>

<p>
We'll end this section with the prototypes for both functions
</p>
<pre>
/* 
 * Set the 8 LEDs in a row to a new state
 * Params:
 * int addr   The address of the display to control
 * int row    The row on which the LEDs are to be set
 *            Only values between 0 and 7 are valid.
 * byte value A bit set to 1 in this value will light up the 
 *            corresponding led.
 */
void setRow(int addr, int row, byte value);

/* 
 * Set the 8 LEDs in a column to a new state
 * Params:
 * int addr   The address of the display to control
 * int col    The column on which the LEDs are to be set
 *            Only values between 0 and 7 are valid.
 * byte value A bit set to 1 in this value will light up the
 *            corresponding led.
*/
void setColumn(int addr, int col, byte value);
</pre>
<p></p>
<a id="Seg7" name="Seg7"></a>
<h2>Controlling 7-segment displays</h2>
<p>
This is going to be much easier than the last section. The picture at the very top of this
page already showed what is possible. I think there is no need for a schematic here, because
from the data-sheet of the MAX72XX it should be quite clear how 7-segment displays are to
be wired. 
</p>
<a id="digits" name="digits"></a>
<h3>Display decimal (or hex) numbers</h3>
<p>
The first function takes a byte-value argument and prints it as the 
corresponding number to the specified digit on a display. The range of
values runs from 0..15. Values between 0 and 9 are printed as numbers, for values
between 10 and 15 the hexadecimal character is printed. 
All other values will simply be ignored. Ignored in this case means, nothing will be
printed. The digit will not be blanked, it will simply retain its last valid value.
The decimal point for the digit is handled by another argument that lets you switch the 
DP-Led on or off.
Here is a little example that prints an int value to a display with (at least) 4 digits.
(It uses a call explained from the next chapter for the sign extension):
</p>
<pre>
void printNumber(int v) {
    int ones;
    int tens;
    int hundreds;
    boolean negative;	

    if(v&lt;0) {
        negative=true;
        v=v*-1;
    }
    ones=v%10;
    v=v/10;
    tens=v%10;
    v=v/10;
    hundreds=v;			
    if(negative) {
       //print a minus on the first MAX72XX, 4'th digit from the right, no decimal-point	
       lc.setChar(0,3,'-',false);
    }
    else {
       //print a blank in the sign column
       lc.setChar(0,3,' ',false);
    }
    //Now print the number digit by digit
    lc.setDigit(0,2,(byte)hundreds,false);
    lc.setDigit(0,1,(byte)tens,false);
    lc.setDigit(0,0,(byte)ones,false);
}
</pre>
<p>
The prototype for the function looks like this:
</p>
<pre>
/* 
 * Display a hexadecimal digit on a 7-Segment Display
 * Params:
 * int addr   the address of the display to control
 * int digit  the position of the digit on the display
 * byte value the value to be displayed. 
 *            Only values between 0x00 and 0x0F are valid.
 * boolean dp If true also switches on the decimal point.
 */
void setDigit(int addr, int digit, byte value, boolean dp);
</pre>
<p>
The <code>digit</code>-argument can be from the range 0..7 because 
the MAX72XX can drive up to 8 7-segment displays and the index starts
at 0 as usual.
</p>
<a id="Characters" name="Characters"></a>
<h3>Displaying characters</h3>
<p>
Although only a limited set of characters can be shown on a 7-segment display, this is 
sometimes very handy. The <code>value</code> argument is of type char and can be from the range
(numeric)0 to numeric(127). For all these value we have a defined character which is
mostly the <code>&lt;SPACE&gt;</code>. But if there is a recognizable representation for a (ASCII-)character
it will be printed to the display. For character values above 127 the <code>&lt;SPACE&gt;</code> character
will be printed. 
</p>
<p>
Here is the set of printable characters:
</p>
<ul>
<li><code>0 1 2 3 4 5 6 7 8 9</code>
</li>
<li><code>A a</code> (prints upper case) 
</li>
<li><code>B b</code> (prints lower case)  
</li>
<li><code>C c</code> (prints lower case)  
</li>
<li><code>D d</code> (prints lower case)  
</li>
<li><code>E e</code> (prints upper case)  
</li>
<li><code>F f</code> (prints upper case)  
</li>
<li><code>H h</code> (prints upper case)  
</li>
<li><code>L l</code> (prints upper case)  
</li>
<li><code>P p</code> (prints upper case)  
</li>
<li><code>-</code> (the minus sign)
</li>
<li><code>.,</code> (lights up the decimal-point)
</li>
<li><code>_</code> (the underscore)
</li>
<li><code>&lt;SPACE&gt;</code> (the blank or space char)
</li>
</ul>

<p></p>
<p>
For convenience reasons the hexadecimal characters have also been redefined at
the char values 0x00...0x0F. For that reason you can simply pass in a byte instead
of a char argument if you want to mix digits and characters on the display.
The prototype of the function is almost the same  as the one for displaying digits.
</p>
<pre>
/* 
 * Display a character on a 7-Segment display.
 * The char that can be actually displayed are obviously quite limited.
 * Here is the whole set :	
 * '0','1','2','3','4','5','6','7','8','9','0',
 * 'A','b','c','d','E','F','H','L','P',
 * '.','-','_',' ' 
 * Params:
 * int addr   the address of the display to control
 * int digit  the position of the character on the display
 * char value the character to be displayed. (See the limited set above!) 
 * boolean dp If true also switches on the decimal point.
*/
void setChar(int addr, int digit, char value, boolean dp);
</pre>
<p></p>
<p>
OK, that was it ... thanks for listening!
</p>
<a id="Download" name="Download"></a>
<h2>Download</h2>
<p>
The file <a href="http://www.wayoda.org/arduino/downloads/LedControl.zip">LedControl.zip</a> contains
the source code for the library and a local version of this documentation.
The zip-file will create a new directory named LedControl with the following contents:
</p>
<ul>
<li>LedControl/LedControl.h   The header to be included into your project
</li>
<li>LedControl/LedControl.cpp The implementation
</li>
<li>LedControl/doc/LedControl.html  The html documentation
</li>
<li>LedControl/doc/lc.css The style sheet for the html documentation
</li>
<li>LedControl/doc/*.jpg Several pictures used in the html documentation
</li>
</ul>

<p></p>
<p>
You have to unpack the zip-file into the library directory of your arduino environment.
I really don't know whether the location library directory has changed with newer or older 
versions of the arduino environment, so I can only tell for my 0007 installation. 
From the arduino root-directory <code>arduino-0007</code> the libraries are located at
</p>
<p>
<code>arduino-0007/lib/targets/libraries/</code>
</p>
<p>
after unpacking <code>LedControl.zip</code> into this directory, the new library has to be compiled.
From the arduino-ide this is very simple:
</p>
<p>
Create a new sketch with the following content:
</p>
<pre>
#include "LedControl.h"

void setup() {}
void loop() {}
</pre>
<p>
Now hit the verify/compile button and the library will be compiled and 
is then available for all of your sketches that start with a <code>#include "LedControl.h</code>
line.
</p>
<a id="Bugs" name="Bugs"></a>
<h2>Known bugs</h2>
<p>
When the library gets compiled inn the arduino-ide, some warnings are issued. 
None of these warnings is relevant for your application code. 
</p>
<p>
There is more to come surely!
</p>
<a id="History" name="History"></a>
<h2>Revision History</h2>
<p>
<em>June 23, 2007</em> First public release
</p>
<a id="Feedback" name="Feedback"></a>
<h2>Feedback</h2>
<p>
Your first stop should be the arduino forum section <code>Hardware/Interfacing</code>
which I visit regularly. But you are also welcome to send questions, 
objections or corrections to &lt;<a href="mailto:e.fahle@wayoda.org">e.fahle@wayoda.org</a>&gt;
</p>
<a id="SoftwareLicence" name="SoftwareLicence"></a>
<h2>License (The software)</h2>
<p>
The source code for this library is released under the Terms of 
the GNU Lesser General Public License version 2.1. 
</p>
<a id="DocLicence" name="DocLicence"></a>
<h2>License (This document)</h2>
<p>
This document is &copy;2007 by Eberhard Fahle.
I make no claims as to the completeness or correctness of the information
contained in this document.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
</p>
</div>

<!-- xhtml code generated by txt2tags 2.4 (http://txt2tags.sf.net) -->
<!-- cmdline: txt2tags -t xhtml LedControl.t2t -->
</body></html>
